/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hnly.djdl

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.lifecycle.Lifecycle
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.navArgument
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navigation
import com.hnly.djdl.global.requestTag
import com.hnly.djdl.MainDestinations.SNACK_ID_KEY
import com.hnly.djdl.home.HomeSections
import com.hnly.djdl.home.findStartDestination
import com.hnly.djdl.home.StoryListPage
import com.hnly.djdl.home.p4.P4Page
import com.hnly.djdl.home.p3.P3Page
import com.hnly.djdl.home.SnackDetail
import com.hnly.djdl.components.CountdownScreen
import com.hnly.djdl.home.p1.P1Page
import com.hnly.djdl.home.p2.GOTO_CALC
import com.hnly.djdl.home.p2.GOTO_KNOW_NAV
import com.hnly.djdl.home.p2.GOTO_MINE_NAV
import com.hnly.djdl.home.p2.GOTO_SPORT_NAV
import com.hnly.djdl.home.p2.GOTO_STORY
import com.hnly.djdl.home.p2.GOTO_THINK_PAGE
import com.hnly.djdl.home.p2.P2Page
import com.hnly.djdl.model.RecordTools
import com.hnly.djdl.model.SnackRepo

/**
 * Destinations used in the ([MainApp]).
 */
object MainDestinations {
    const val HOME_ROUTE = "111111"
    const val SNACK_DETAIL_ROUTE = "222222"
    const val SNACK_ID_KEY = "333333"
    const val ADD_EXPERIENCE = "4444444"
    const val THINK = "555555"
    const val STORY = "66666"
}

@Composable
fun MainNavGraph(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
    startDestination: String = MainDestinations.HOME_ROUTE,
) {
    navController.addOnDestinationChangedListener { _, destination, _ ->
        val route: String = destination.route ?: ""
        requestTag(route)
    }
    val feedback = LocalHapticFeedback.current
    val context = LocalContext.current
    LaunchedEffect(Unit) {
        RecordTools.checkInit(context)
    }
    NavHost(
        navController = navController,
        startDestination = startDestination,
        modifier = modifier
    ) {
        navigation(
            route = MainDestinations.HOME_ROUTE,
            startDestination = HomeSections.FIR.route
        ) {
            composable(HomeSections.FIR.route) { from: NavBackStackEntry ->
                P1Page(modifier) { snackId ->
                    feedback.performHapticFeedback(HapticFeedbackType.LongPress)
                    if (from.lifecycleIsResumed()) {
                        RecordTools.add(context, SnackRepo.getSnack(snackId))
                        navController.navigateToSnackDetail(snackId)
                    }
                }
            }
            composable(HomeSections.SEC.route) { from ->
                P2Page(
                    modifier,
                    clickToDetail = { snackId: Long ->
                        feedback.performHapticFeedback(HapticFeedbackType.LongPress)
                        if (from.lifecycleIsResumed()) {
                            RecordTools.add(context, SnackRepo.getSnack(snackId))
                            navController.navigateToSnackDetail(snackId)
                        }
                    },
                    clickCard = { id ->
                        feedback.performHapticFeedback(HapticFeedbackType.LongPress)
                        if (from.lifecycleIsResumed()) {
                            when (id) {
                                GOTO_SPORT_NAV -> navController.navigateToNav(HomeSections.SEC.route)
//                                GOTO_KNOW_NAV -> navController.navigateToNav(HomeSections.THI.route)
                                GOTO_MINE_NAV -> navController.navigateToNav(HomeSections.FOU.route)
                                GOTO_THINK_PAGE -> navController.navigate(MainDestinations.THINK)
                                GOTO_STORY -> navController.navigate(MainDestinations.STORY)
                                GOTO_CALC -> navController.navigateToNav(HomeSections.FIR.route)
                            }
                        }
                    }
                )
            }
//            composable(HomeSections.THI.route) { from ->
//                P3Page(onSnackClick = { snack ->
//                    feedback.performHapticFeedback(HapticFeedbackType.LongPress)
//                    if (from.lifecycleIsResumed()) {
//                        RecordTools.add(context, SnackRepo.getSnack(snack.id))
//                        navController.navigate("${MainDestinations.SNACK_DETAIL_ROUTE}/${snack.id}")
//                    }
//                }, modifier)
//            }
            composable(HomeSections.FOU.route) {
                P4Page(modifier)
            }
        }
        composable(
            "${MainDestinations.SNACK_DETAIL_ROUTE}/{$SNACK_ID_KEY}",
            arguments = listOf(navArgument(SNACK_ID_KEY) { type = NavType.LongType })
        ) { backStackEntry ->
            val arguments = requireNotNull(backStackEntry.arguments)
            val snackId = arguments.getLong(SNACK_ID_KEY)
            SnackDetail(
                snackId = snackId,
                upPress = {
                    navController.navigateUp()
                }
            )
        }
        composable(MainDestinations.THINK) {
            CountdownScreen(1800) {
                navController.navigateUp()
            }
        }
        composable(MainDestinations.STORY) {
            StoryListPage(
                onBackClick = {
                    navController.navigateUp()
                }
            )
        }
    }
}

/**
 * If the lifecycle is not resumed it means this NavBackStackEntry already processed a nav event.
 * This is used to de-duplicate navigation events.
 */
private fun NavBackStackEntry.lifecycleIsResumed() =
    this.lifecycle.currentState == Lifecycle.State.RESUMED

private fun NavHostController.navigateToNav(route: String) {
    navigate(route) {
        launchSingleTop = true
        restoreState = true
        popUpTo(findStartDestination(graph).id) {
            saveState = true
        }
    }
}

private fun NavHostController.navigateToSnackDetail(snackId: Long) {
    this.navigate("${MainDestinations.SNACK_DETAIL_ROUTE}/${snackId}")
}
